package web_controller

import (
	"github.com/duke-git/lancet/v2/convertor"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"strconv"
	"transport/framework/fw_db/fw_db_self"
	"transport/framework/fw_event"
	"transport/framework/fw_middleware"
	"transport/framework/fw_utils"
	"transport/web/web_mapper"
	"transport/web/web_model"
	"transport/web/web_vo"
)

type orderController struct {
}

func (controller *orderController) ItemById(c *gin.Context) {
	id, _ := convertor.ToInt(c.Param("id"))
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	item, err := mapper.QueryById(id)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, item, "ok")
}
func (controller *orderController) DelById(c *gin.Context) {
	id, _ := convertor.ToInt(c.Param("id"))
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	err := mapper.DeleteById(id)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, "", "ok")
}
func (controller *orderController) DelByIds(c *gin.Context) {
	var ids []int64
	err := c.ShouldBindJSON(&ids)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	err = mapper.DeleteByIds(ids)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, "", "ok")
}
func (controller *orderController) CreateOrUpdateItem(c *gin.Context) {
	var data web_model.TransOrder
	err := c.ShouldBindJSON(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	_, err = mapper.CreateOrUpdate(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, "", "ok")
}
func (controller *orderController) OrderArrived(c *gin.Context) {
	var data web_vo.UpdateOrderStatus
	err := c.ShouldBindJSON(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	err = fw_db_self.GetSqliteDB().Transaction(func(tx *gorm.DB) error {
		mapperOrder := web_mapper.OrderrMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		mapperBill := web_mapper.TransBillMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		// 是否全部送达
		err = mapperOrder.UpdateStatus(data.OrderCode, data.Status)
		if err != nil {
			return err
		}
		err = mapperBill.UpdateArrivedOkStatus(data.BillSn, "3")
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, "", "ok")
}
func (controller *orderController) CreateItem(c *gin.Context) {
	var data web_model.TransOrder
	err := c.ShouldBindJSON(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	ret, err := mapper.Create(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, ret, "ok")
}

func (controller *orderController) SyncInfo(c *gin.Context) {
	fw_event.EventChanDelivery(fw_event.EVENT_CMD_SYNC_ORDER_INFO, "", "", "")
	fw_utils.OK(c, "", "ok")
}
func (controller *orderController) UpdateBillInfo(c *gin.Context) {
	var data web_vo.UpdateBillInfo
	err := c.ShouldBindJSON(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	err = mapper.UpdateBillInfo(data.ID, data.BillId, data.BillSn)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, "", "ok")
}

func (controller *orderController) UpdateItem(c *gin.Context) {
	var data web_model.TransOrder
	err := c.ShouldBindJSON(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	ret, err := mapper.Update(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, ret, "ok")
}
func (controller *orderController) Page(c *gin.Context) {
	var err error
	var from, limit = 1, 10
	if tmp := c.Request.FormValue("pageSize"); tmp != "" {
		limit, _ = strconv.Atoi(tmp)
	}
	if tmp := c.Request.FormValue("pageIndex"); tmp != "" {
		from, _ = strconv.Atoi(tmp)
	}
	orderCode := c.Request.FormValue("orderCode")
	billSn := c.Request.FormValue("billSn")
	customerName := c.Request.FormValue("customerName")
	routeName := c.Request.FormValue("routeName")
	priorityLevel := c.Request.FormValue("priorityLevel")
	status := c.Request.FormValue("status")
	tempType := c.Request.FormValue("tempType")
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	items, total, err := mapper.Page(from, limit, orderCode, billSn, customerName, routeName, priorityLevel, status, tempType)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.PageOK(c, items, total, from, limit, "ok")
}

func (controller *orderController) pageNotBind(c *gin.Context) {
	var err error
	var from, limit = 1, 10
	if tmp := c.Request.FormValue("pageSize"); tmp != "" {
		limit, _ = strconv.Atoi(tmp)
	}
	if tmp := c.Request.FormValue("pageIndex"); tmp != "" {
		from, _ = strconv.Atoi(tmp)
	}
	orderCode := c.Request.FormValue("orderCode")
	billSn := c.Request.FormValue("billSn")
	customerName := c.Request.FormValue("customerName")
	routeName := c.Request.FormValue("routeName")
	priorityLevel := c.Request.FormValue("priorityLevel")
	status := c.Request.FormValue("status")
	tempType := c.Request.FormValue("tempType")
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	items, total, err := mapper.PageNotBind(from, limit, orderCode, billSn, customerName, routeName, priorityLevel, status, tempType)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.PageOK(c, items, total, from, limit, "ok")
}
func (controller *orderController) PageApp(c *gin.Context) {
	var err error
	var from, limit = 1, 10
	if tmp := c.Request.FormValue("pageSize"); tmp != "" {
		limit, _ = strconv.Atoi(tmp)
	}
	if tmp := c.Request.FormValue("pageIndex"); tmp != "" {
		from, _ = strconv.Atoi(tmp)
	}
	billSn := c.Request.FormValue("billSn")
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	items, total, err := mapper.PageApp(from, limit, billSn)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.PageOK(c, items, total, from, limit, "ok")
}
func (controller *orderController) List(c *gin.Context) {
	var err error
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	billSn := c.Request.FormValue("billSn")
	status := c.Request.FormValue("status")
	items, total, err := mapper.List(billSn, status)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.ListOK(c, items, total, "ok")
}
func (controller *orderController) ListApp(c *gin.Context) {
	var err error
	mapper := web_mapper.OrderrMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	billSn := c.Request.FormValue("billSn")
	items, total, err := mapper.ListApp(billSn)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.ListOK(c, items, total, "ok")
}
func OrderRoute(r *gin.Engine) {
	controller := orderController{}
	v1 := r.Group("/trans").Use(fw_middleware.JwtAuthMiddleware())
	{
		v1.GET("/v1/order/page", controller.Page)
		v1.GET("/v1/order/pageApp", controller.PageApp)
		v1.GET("/v1/order/pageNotBind", controller.pageNotBind)
		v1.GET("/v1/order/list", controller.List)
		v1.GET("/v1/order/listApp", controller.ListApp)
		v1.GET("/v1/order/:id", controller.ItemById)
		v1.DELETE("/v1/order/:id", controller.DelById)
		v1.DELETE("/v1/order/batchByIds", controller.DelByIds)
		v1.PUT("/v1/order", controller.UpdateItem)
		v1.POST("/v1/order", controller.CreateItem)
		v1.POST("/v1/orderSync", controller.SyncInfo)
		v1.POST("/v1/updateBillInfo", controller.UpdateBillInfo)
		v1.POST("/v1/orderItemCreateOrUpdate", controller.CreateOrUpdateItem)
		v1.POST("/v1/orderArrived", controller.OrderArrived)
	}
}
